package com.sky.service.impl;

import com.aliyun.oss.common.utils.StringUtils;
import com.sky.dto.GoodsSalesDTO;
import com.sky.entity.User;
import com.sky.mapper.ReportMapper;
import com.sky.mapper.WorkspaceMapper;
import com.sky.service.ReportService;
import com.sky.service.WorkspaceService;
import com.sky.vo.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class ReportServiceImpl implements ReportService {

    @Autowired
    private ReportMapper reportMapper;

    /**
     * 营业额统计
     * @param begin
     * @param end
     * @return
     */
    public TurnoverReportVO turnoverStatistics(LocalDate begin, LocalDate end) {
        List<LocalDate> dateList = new ArrayList<>();
        while (begin.isBefore(end)) {
            dateList.add(begin);
            begin = begin.plusDays(1);
        }
        dateList.add(end);
        String dates = dateList.stream()
                .map(LocalDate::toString)
                .collect(Collectors.joining(","));

        List<BigDecimal> amountList = new ArrayList<>();
        for (LocalDate date : dateList) {
            BigDecimal amount = reportMapper.getAmountByDate(date);
            if (amount != null) {
                amountList.add(amount);
            }else{
                amountList.add(BigDecimal.ZERO);
            }
        }
        String amounts = amountList.stream()
                .map(BigDecimal::toPlainString)
                .collect(Collectors.joining(","));

        TurnoverReportVO turnoverReportVO = new TurnoverReportVO();
        turnoverReportVO.setDateList(dates);
        turnoverReportVO.setTurnoverList(amounts);

        return turnoverReportVO;
    }

    /**
     * 用户统计
     * @param begin
     * @param end
     * @return
     */
    public UserReportVO userStatistics(LocalDate begin, LocalDate end) {
        List<LocalDate> dateList = new ArrayList<>();
        while (begin.isBefore(end)) {
            dateList.add(begin);
            begin = begin.plusDays(1);
        }
        dateList.add(end);
        String dates = dateList.stream()
                .map(LocalDate::toString)
                .collect(Collectors.joining(","));

        List<Long> newUserList = new ArrayList<>();
        List<Long> totalUserList = new ArrayList<>();
        Long totalUser = reportMapper.getTotalUserByDate(dateList.get(0).minusDays(1));
        for (LocalDate date : dateList) {
            Long newUserCount = reportMapper.getNewUserCountByDate(date);
            if (newUserCount != null) {
                newUserList.add(newUserCount);
                totalUser += newUserCount;
            }else{
                newUserList.add(0L);
            }
            totalUserList.add(totalUser);
        }
        String newUsers = newUserList.stream()
                .map(String::valueOf)
                .collect(Collectors.joining(","));
        String totalUsers = totalUserList.stream()
                .map(String::valueOf)
                .collect(Collectors.joining(","));

        UserReportVO userReportVO = UserReportVO.builder().dateList(dates)
                .newUserList(newUsers)
                .totalUserList(totalUsers).build();
        return userReportVO;
    }

    /**
     * 订单统计
     * @param begin
     * @param end
     * @return
     */
    public OrderReportVO orderStatistics(LocalDate begin, LocalDate end) {
        List<LocalDate> dateList = new ArrayList<>();
        while (begin.isBefore(end)) {
            dateList.add(begin);
            begin = begin.plusDays(1);
        }
        dateList.add(end);
        String dates = dateList.stream()
                .map(LocalDate::toString)
                .collect(Collectors.joining(","));

        List<Long> orderList = new ArrayList<>();
        List<Long> completedOrderList = new ArrayList<>();
        Integer totalOrder = 0;
        Integer totalCompletedOrder = 0;
        for(LocalDate date : dateList) {
            Long completedOrder = reportMapper.getCompletedOrderByDate(date);
            Long order = reportMapper.getOrderByDate(date);
            if (completedOrder == null) completedOrder = 0L;
            if (order == null) order = 0L;
            totalOrder += Math.toIntExact(order);
            totalCompletedOrder += Math.toIntExact(completedOrder);
            completedOrderList.add(completedOrder);
            orderList.add(order);
        }
        Double orderCompletionRate = totalCompletedOrder.doubleValue() / totalOrder.doubleValue();
        String orders = orderList.stream()
                .map(String::valueOf)
                .collect(Collectors.joining(","));
        String completedOrders = completedOrderList.stream()
                .map(String::valueOf)
                .collect(Collectors.joining(","));


        return OrderReportVO.builder().dateList(dates)
                .orderCountList(orders)
                .totalOrderCount(totalOrder)
                .validOrderCount(totalCompletedOrder)
                .validOrderCountList(completedOrders)
                .orderCompletionRate(orderCompletionRate).build();
    }

    /**
     * 销量top10统计
     * @param begin
     * @param end
     * @return
     */
    public SalesTop10ReportVO top10(LocalDate begin, LocalDate end) {
        List<GoodsSalesDTO> goodSales = reportMapper.getGoodSales(begin,end);

        String names = goodSales.stream()
                .map(GoodsSalesDTO::getName)
                .collect(Collectors.joining(","));
        String numbers = "";
        for (int i = 0; i < goodSales.size(); i++) {
            numbers += goodSales.get(i).getNumber();
            if (i != goodSales.size() - 1) {
                numbers += ",";
            }
        }

        return SalesTop10ReportVO.builder().nameList(names).numberList(numbers).build();
    }
}
